package com.jason.www.common;

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ListToMap {
    public class Apple {
        private Integer id;
        private String name;
        private Double money;
        private Integer num;
        public Apple(Integer id, String name, Double money, Integer num) {
            this.id = id;
            this.name = name;
            this.money = money;
            this.num = num;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Double getMoney() {
            return money;
        }

        public void setMoney(Double money) {
            this.money = money;
        }

        public Integer getNum() {
            return num;
        }

        public void setNum(Integer num) {
            this.num = num;
        }

        @Override
        public String toString() {
            return "Apple{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", money=" + money +
                    ", num=" + num +
                    '}';
        }
    }

    List<Apple> appleList = new ArrayList<>();//存放apple对象集合

    @Before
    public void initData(){
        Apple apple1 =  new Apple(1,"苹果1",3.25,10);
        Apple apple12 = new Apple(1,"苹果2",1.35,20);
        Apple apple2 =  new Apple(2,"香蕉",2.89,30);
        Apple apple3 =  new Apple(3,"荔枝",9.99,40);
        Apple apple4 = null;
        appleList.add(apple1);
        appleList.add(apple12);
        appleList.add(apple2);
        appleList.add(apple3);
        appleList.add(apple4);
    }

    /**
     *  过滤filter  满足条件的不过滤
     *  例如  appleList过滤掉null值
     */
    @Test
    public void listFilter(){
        List<Apple> list = appleList.stream().filter(Objects::nonNull).collect(Collectors.toList());
        System.out.println(list);
    }


    /**
     * List -> Map
     * 需要注意的是：
     * toMap 如果集合对象有重复的key，会报错Duplicate key ....
     *  apple1,apple12的id都为1。
     *  可以用 (k1,k2)->k1 来设置，如果有重复的key,则保留key1,舍弃key2
     */
    @Test
    public void listToMap(){
        //Map<Integer, Apple> map = appleList.stream().collect(Collectors.toMap(apple -> apple.getId(), apple -> apple));//重复key会报错java.lang.IllegalStateException: Duplicate key
        //Map<Integer, Apple> map = appleList.stream().collect(Collectors.toMap(Apple::getId, Function.identity()));//另一种写法 Function.identity()代表apple本身
        Map<String, Double> map = appleList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(Apple::getName, Apple::getMoney));
        Map<Integer, Apple> map2 = appleList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(Apple::getId, Function.identity(),(k1, k2)->k1));

        System.out.println(map);
    }

    /**
     * List里面的对象元素，以某个属性来分组，例如，以id分组，将id相同的放在一起：
     */
    @Test
    public void listToMapGroup(){
        Map<Integer, List<Apple>> map = appleList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.groupingBy(Apple::getId));
        System.out.println(map);
    }

    /**
     * 计算list 中某个属性的总和
     */
    @Test
    public void listToTotal(){
        Double totalMoney = appleList.stream()
                .filter(Objects::nonNull)
                .map(Apple::getMoney)
                .reduce(0.0, this::add);
        double sum = appleList.stream()
                .filter(Objects::nonNull)
                .mapToDouble(Apple::getMoney).sum();
        System.out.println(totalMoney);
        System.out.println(sum);

    }

    private Double add(Double a, Double b) {
        return a + b;
    }
}
